package com.jltx.xq.simplewatch.news.model.impl;

import android.text.TextUtils;

import com.google.gson.reflect.TypeToken;
import com.jltx.xq.simplewatch.db.helper.NewsRecordDBHelper;
import com.jltx.xq.simplewatch.db.helper.NewsStateDBHelper;
import com.jltx.xq.simplewatch.news.model.IWeChatLocalNewsModel;
import com.jltx.xq.simplewatch.news.model.IWeChatNewsModel;
import com.jltx.xq.simplewatch.news.model.bean.NewsRecord;
import com.jltx.xq.simplewatch.news.model.bean.NewsState;
import com.jltx.xq.simplewatch.news.model.bean.WeChatNews;
import com.jltx.xq.simplewatch.utils.GsonFactoryUtils;
import com.jltx.xq.simplewatch.utils.ListUtils;
import com.jltx.xq.simplewatch.utils.NewsStateUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cn.jltx.utils.XqLog;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * @author jltxseo
 *         Created by junlintianxia on 2017/08/23.
 */

public class WeChatNewsLocalModelImpl implements IWeChatNewsModel,IWeChatLocalNewsModel {

    private Integer lastNewsRecordPage; //缓存当前本地数据库上拉后的最后一组新闻数据的页码

    @Override
    public Observable<List<WeChatNews>> getWeChatNews(String channel, int limitNum,boolean isDown) {
        if(!isHadCacheNewsRecord()){
            lastNewsRecordPage = 0;
            XqLog.d(WeChatNewsModelImpl.TAG, "第一次进入页面加载上次最后的一页"+Thread.currentThread());
            return getLocalNewsRecord(channel,0,true);
        }else {
            XqLog.d(WeChatNewsModelImpl.TAG, "上拉加载上一页新闻数据"+Thread.currentThread());
            return getLocalNewsRecord(channel,lastNewsRecordPage - 1,false).delay(800, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public boolean isHadCacheNewsRecord() {
        boolean isHad;
        if(lastNewsRecordPage == null){
            isHad = false;
        }else {
            isHad = true;
        }
        return isHad;
    }

    @Override
    public Integer getLastNewsRecordPage() {
        return lastNewsRecordPage;
    }

    /**
     *
     * @param channel
     * @param page
     * @param isLast
     * @return
     */
    public Observable<List<WeChatNews>> getLocalNewsRecord(final String channel, final int page, boolean isLast) {
        Observable<NewsRecord> newsRecordObservable;
        if (isLast) {
            newsRecordObservable = getLastNewsRecord(channel);
        } else {
            newsRecordObservable = getNewsRecord(channel, page);
        }

        Observable<List<WeChatNews>> localNewsObservalbe = newsRecordObservable
                .observeOn(Schedulers.io())
                .map(new Function<NewsRecord, List<WeChatNews>>() {  //将NewRecord里面的data数据解析成新闻的列表
                    @Override
                    public List<WeChatNews> apply(@NonNull NewsRecord newsRecord) throws Exception {
                        XqLog.d(WeChatNewsModelImpl.TAG, "将由数据库加载进来的新闻数据解析成新闻的列表" + Thread.currentThread());
                        List<WeChatNews> result = new ArrayList<WeChatNews>();
                        if (newsRecord != null && !TextUtils.isEmpty(newsRecord.getData())) {
                            try {
                                result = GsonFactoryUtils.providerGson().fromJson(newsRecord.getData(), new TypeToken<List<WeChatNews>>() {
                                }.getType()); //gson 解析新闻列表
                                if (result != null) {
                                    WeChatNews weChatNews;
                                    Iterator<WeChatNews> iterator = result.iterator();
                                    while (iterator.hasNext()) { //依次通过channel和对应的新闻bean的url做为key去获取新闻已读和删除的状态
                                        weChatNews = iterator.next();
                                        NewsState newsState = NewsStateDBHelper.getNewsState(channel, NewsStateUtils.convertWetChatNewsStateKey(weChatNews));  //通过channel和对应的新闻bean的url做为key去获取新闻已读和删除的状态
                                        if (newsState != null) {
                                            weChatNews.setIsRead(newsState.getIs_read()); //设置到已经存在的新闻bean里面
                                            weChatNews.setIsDel(newsState.getIs_del());
                                        }

                                        if(weChatNews.getIsDel() != 0){
                                            iterator.remove();
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                XqLog.d(WeChatNewsModelImpl.TAG, "parser erro for news record");
                            }
                        }
                        if (!ListUtils.isEmpty(result)) {
                            XqLog.d(WeChatNewsModelImpl.TAG, "数据库不为空");
                        }
                        return result;
                    }
                });
        return localNewsObservalbe;
    }

    /**
     * 刚运行程序第一次进页面时把上一次page为最大页面的新闻数据从数据库里面读取
     * @param channel
     * @return
     */
    public Observable<NewsRecord> getLastNewsRecord(final String channel) {
        Observable<NewsRecord> lastNewsRecordObservalbe = Observable.create(new ObservableOnSubscribe<NewsRecord>() {
            @Override
            public void subscribe(ObservableEmitter<NewsRecord> e) throws Exception {
                XqLog.d(WeChatNewsModelImpl.TAG, "刚进页面第一次加载数据库里页码为最大的新闻数据" + Thread.currentThread());
                NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecordNoNull(channel); //根据频道名获取上一次page为最大页面的新闻数据
                e.onNext(newsRecord);
                e.onComplete();  //onnext之后记得一定要调用onComplete
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<NewsRecord>() {
                    @Override
                    public void accept(@NonNull NewsRecord newsRecord) throws Exception {
                        XqLog.d(WeChatNewsModelImpl.TAG, "将由数据库加载进来页码为最大的新闻数据缓存到cacheNewsRecord变量" + Thread.currentThread());
                        if (newsRecord != null && newsRecord.getPage() != 0) {
                            lastNewsRecordPage = newsRecord.getPage();
                        } else {
                            XqLog.d(WeChatNewsModelImpl.TAG, "newsRecord  had no data");
                        }
                    }
                });
        return lastNewsRecordObservalbe;
    }

    /**
     * 上拉时去新闻数据库里面取上一页对应的新闻数据
     * @param channel
     * @param page
     * @return
     */
    public Observable<NewsRecord> getNewsRecord(final String channel, final int page) {
        Observable<NewsRecord> newsRecordObservalbe = Observable.create(new ObservableOnSubscribe<NewsRecord>() {
            @Override
            public void subscribe(ObservableEmitter<NewsRecord> e) throws Exception {
                XqLog.d(WeChatNewsModelImpl.TAG, "开始加载本地对应页面的数据"+Thread.currentThread());
                NewsRecord newsRecord = NewsRecordDBHelper.getNewsRecordNoNull(channel, page); //根据频道channel和page获取对应页面的新闻数据
                e.onNext(newsRecord);
                e.onComplete();  //onnext之后记得一定要调用onComplete
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<NewsRecord>() {
                    @Override
                    public void accept(@NonNull NewsRecord newsRecord) throws Exception {
                        XqLog.d(WeChatNewsModelImpl.TAG, "将由数据库加载进来的最新新闻数据缓存到cacheNewsRecord变量" + Thread.currentThread());
                        if (newsRecord != null && newsRecord.getPage() != 0 && newsRecord.getPage() == page) {
                            lastNewsRecordPage = newsRecord.getPage();
                        } else {
                            XqLog.d(WeChatNewsModelImpl.TAG, "newsRecord  had no data");
                        }
                    }
                });
        return newsRecordObservalbe;
    }

    @Override
    public Observable<Integer> updateNewsState(String channel, String key, int isRead, int isDel) {
        return Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                XqLog.d(WeChatNewsModelImpl.TAG, "将新闻选中状态记录到数据库" + Thread.currentThread());
                NewsStateDBHelper.addOrUpdateNewsState(channel,key,isRead,isDel);
                e.onNext(1);
                e.onComplete(); //onnext之后记得一定要调用onComplete
            }
        })
        .subscribeOn(Schedulers.io());
    }
}
